package com.ccc.boot.security.service.impl;

import com.ccc.boot.constant.DictConstant;
import com.ccc.boot.exception.BusinessException;
import com.ccc.boot.response.ResponseCode;
import com.ccc.boot.security.pojo.AuthorityData;
import com.ccc.boot.security.service.UserService;
import com.ccc.boot.system.entity.SysUser;
import com.ccc.boot.system.service.SysRoleService;
import com.ccc.boot.system.service.SysUserService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 自定义认证与授权
 *
 * @author superC
 * @version 0.1.0
 * @date 2022/3/23
 */

@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysRoleService sysRoleService;

    /**
     * 通过用户名获取用户信息
     *
     * @param username
     * @return {@link UserDetails}
     * @date 2022/4/12 14:13
     * @author superC
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        /**
         * 获取用户
         */
        SysUser sysUser = sysUserService.getUserInfo(username);
        if (!sysUser.getStatus().equals(DictConstant.USER_STATUS_OK)) {
            throw new BusinessException(ResponseCode.USER_ACCOUNT_FORBIDDEN);
        }

        /**
         * 获取用户所拥有的角色
         */
        List<String> roleList = sysRoleService.getRoleCodes(sysUser.getId());
        // 用户无权限
        if (roleList == null || roleList.isEmpty()) {
            throw new BusinessException(ResponseCode.USER_NO_ROLE);
        }
        // 给用户授予权限
        Set<AuthorityData> authorityList = new HashSet<>();
        roleList.forEach(code -> {
            authorityList.add(new AuthorityData(code));
        });

        // 由框架完成认证工作
        return new User(sysUser.getUsername(), sysUser.getPassword(), authorityList);
    }

}